package com.example.stujava.module.xiangxue.reflect.inject_view

import android.app.Activity
import android.os.Parcelable
import android.view.View
import java.util.*

object InjectViewUtils {

    fun init(act: Activity) {
        val actClass = act.javaClass
        val fields = actClass.declaredFields
        fields.forEach {
            //判断属性是否被自己的注解声明
            if (it.isAnnotationPresent(ViewId::class.java)) {
                //获取注解
                val viewIdAnnotation = it.getAnnotation(ViewId::class.java)
                //获取到Id值
                val viewId = viewIdAnnotation.value
                //获取View
                val view = act.findViewById<View>(viewId)
                //设置访问权限，运行操作private
                it.isAccessible = true
                //反射赋值
                it.set(act, viewId)
            }
        }
    }

    fun intentInit(act: Activity) {
        val bundle = act.intent.extras ?: return
        val cls = act.javaClass
        val fields = cls.declaredFields
        for (field in fields) {
            if (field.isAnnotationPresent(IntentParams::class.java)) {
                val annotation = field.getAnnotation(IntentParams::class.java)
                //获取key
                val key = annotation.name ?: field.name
                if (bundle.containsKey(key)) {
                    var value = bundle.get(key)
                    //获取元素类型
                    //Parcelable数组 不能直接赋值，其他类型可以；
                    val componentType = field.type.componentType
                    if (field.type.isArray && Parcelable::class.java.isAssignableFrom(componentType)) {
                        val objs = value as Array<*>
                        //创建对应的类型数组，并拷贝
                        // --java代码
                        // Object[] objects = Arrays.copyOf(objs, objs.length, (Class<? extends Object[]>) field.getType());
                        val objects: Array<Any> = Arrays.copyOf(objs, objs.size, field.type as Class<out Array<Any?>?>)
                        value = objects
                    }
                    field.isAccessible = true
                    field.set(act, value)
                }
            }
        }
    }
}